export async function* radixSort(array, compare, swap, set) {
    const n = array.length;
    if (n <= 1) {
        yield { type: 'complete' };
        return;
    }

    // Find the maximum number to know number of digits
    let max = array[0];
    for (let i = 1; i < n; i++) {
        if (array[i] > max) max = array[i];
    }

    // Do counting sort for every digit
    let exp = 1;
    while (Math.floor(max / exp) > 0) {
        yield* countingSortByDigit(array, exp, set);
        exp *= 10;
    }

    yield { type: 'complete' };
}

async function* countingSortByDigit(array, exp, set) {
    const n = array.length;
    const output = new Array(n);
    const count = new Array(10).fill(0);

    // Store count of occurrences in count[]
    for (let i = 0; i < n; i++) {
        const digit = Math.floor(array[i] / exp) % 10;
        count[digit]++;
    }

    // Change count[i] so that count[i] contains actual
    // position of this digit in output[]
    for (let i = 1; i < 10; i++) {
        count[i] += count[i - 1];
    }

    // Build the output array
    for (let i = n - 1; i >= 0; i--) {
        const digit = Math.floor(array[i] / exp) % 10;
        output[count[digit] - 1] = array[i];
        count[digit]--;
    }

    // Copy the output array to array[]
    for (let i = 0; i < n; i++) {
        array[i] = output[i];
        yield { type: 'set', index: i, value: array[i] };
    }
}